package com.yami.shop.multishop.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.app.dto.MyOrderDto;
import com.yami.shop.bean.enums.DeliveryType;
import com.yami.shop.bean.enums.OrderStatus;
import com.yami.shop.bean.event.OrderChangeAddrEvent;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.model.OrderVirtualInfo;
import com.yami.shop.bean.model.UserAddrOrder;
import com.yami.shop.bean.param.OrderChangeAddrParam;
import com.yami.shop.bean.param.OrderParam;
import com.yami.shop.bean.vo.UnDeliveryOrderExcelVO;
import com.yami.shop.common.annotation.SysLog;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ResponseEnum;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.delivery.common.param.DeliveryOrderItemParam;
import com.yami.shop.delivery.common.service.DeliveryOrderService;
import com.yami.shop.delivery.common.service.OrderSelfStationService;
import com.yami.shop.mystery.common.model.ActivitySubject;
import com.yami.shop.mystery.common.service.ActivitySubjectService;
import com.yami.shop.security.multishop.util.SecurityUtils;
import com.yami.shop.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author lgh on 2018/09/15.
 */
@RestController
@RequestMapping("/order/order")
@Tag(name = "订单接口")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private OrderVirtualInfoService orderVirtualInfoService;

    @Autowired
    private UserAddrOrderService userAddrOrderService;

    @Autowired
    private OrderExcelService orderExcelService;

    @Autowired
    private DeliveryOrderService deliveryOrderService;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private OrderSelfStationService orderSelfStationService;
    @Autowired
    private ActivitySubjectService activitySubjectService;

    @GetMapping("/page")
    @Operation(summary =  "分页获取订单列表", description = "分页获取订单列表")
    public ServerResponseEntity<IPage<Order>> page(@ParameterObject OrderParam orderParam, PageParam<Order> page) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        orderParam.setShopId(shopId);
        // 通过活动专题获取活动
        if(ObjectUtil.isNotEmpty(orderParam.getSubjectActivityId())){
            ActivitySubject activitySubject = activitySubjectService.getById(orderParam.getSubjectActivityId());
            if(ObjectUtil.isNotEmpty(activitySubject.getActivityId())){
                orderParam.setActivityIds(Arrays.asList(activitySubject.getActivityId().split(",")));
            }
        }
        IPage<Order> orderPage = orderService.pageOrdersDetailByOrderParam(page, orderParam);
        return ServerResponseEntity.success(orderPage);
    }

    @GetMapping("/orderInfo/{orderNumber}")
    @Operation(summary =  "根据订单号获取订单信息", description = "根据订单号获取订单信息")
    public ServerResponseEntity<Order> info(@PathVariable("orderNumber") String orderNumber) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        Order order = orderService.getOrderByOrderNumberAndShopId(orderNumber, shopId, true);
        List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderNumber);
        order.setOrderItems(orderItems);
        UserAddrOrder userAddrOrder = userAddrOrderService.getById(order.getAddrOrderId());
        order.setUserAddrOrder(userAddrOrder);
        if(Objects.equals(order.getOrderMold(),1)){
            List<OrderVirtualInfo> orderVirtualInfos = orderVirtualInfoService.list(new LambdaQueryWrapper<OrderVirtualInfo>().eq(OrderVirtualInfo::getOrderNumber, orderNumber).eq(OrderVirtualInfo::getIsWriteOff, 0));
            List<String> codes = new ArrayList<>();
            if(CollectionUtil.isNotEmpty(orderVirtualInfos)){
                codes = orderVirtualInfos.stream().map(OrderVirtualInfo::getWriteOffCode).collect(Collectors.toList());
            }
            order.setWriteOffCodes(codes);
        }
        return ServerResponseEntity.success(order);
    }

    @GetMapping("/getOrderByCode")
    @Operation(summary =  "通过提货码获取自提订单", description = "商家扫码获取自提订单")
    @Parameter(name = "code", description = "提货码", required = true)
    public ServerResponseEntity<Order> getStationOrderByCode(@RequestParam(name="code", required = true) String code) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        MyOrderDto myOrderDto = orderSelfStationService.getOrderByStationCode(null, shopId, code);
        Order order = orderService.getOrderByOrderNumberAndShopId(myOrderDto.getOrderNumber(), shopId, true);
        List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(myOrderDto.getOrderNumber());
        order.setOrderItems(orderItems);
        UserAddrOrder userAddrOrder = userAddrOrderService.getById(order.getAddrOrderId());
        order.setUserAddrOrder(userAddrOrder);
        if(Objects.equals(order.getOrderMold(),1)){
            List<OrderVirtualInfo> orderVirtualInfos = orderVirtualInfoService.list(new LambdaQueryWrapper<OrderVirtualInfo>().eq(OrderVirtualInfo::getOrderNumber, myOrderDto.getOrderNumber()).eq(OrderVirtualInfo::getIsWriteOff, 0));
            List<String> codes = new ArrayList<>();
            if(CollectionUtil.isNotEmpty(orderVirtualInfos)){
                codes = orderVirtualInfos.stream().map(OrderVirtualInfo::getWriteOffCode).collect(Collectors.toList());
            }
            order.setWriteOffCodes(codes);
        }
        return ServerResponseEntity.success(order);
    }

    @PutMapping("/changeAmount")
    @Operation(summary =  "修改订单金额", description = "修改订单金额")
    public ServerResponseEntity<Void> changeAmount(@RequestBody Order order) {
        if (order.getFreightAmount() < 0) {
            // 运费不能小于零
            throw new YamiShopBindException("yami.product.dvy.fee");
        }
        if (Objects.isNull(order.getFreightAmount())) {
            order.setFreightAmount(0.00);
        }
        orderService.changeAmount(order);
        return ServerResponseEntity.success();
    }

    @GetMapping("/getChangeAmount")
    @Operation(summary =  "查询修改订单地址后的运费")
    public ServerResponseEntity<Double> getChangeAmount(@ParameterObject OrderChangeAddrParam order) {
        double changeAmount = 0.0;
        OrderChangeAddrEvent orderChangeAddrEvent = new OrderChangeAddrEvent(order, changeAmount);
        applicationContext.publishEvent(orderChangeAddrEvent);
        return ServerResponseEntity.success(orderChangeAddrEvent.getChangeAmount());
    }

    @PutMapping("/changeUserAddr")
    @Operation(summary =  "修改用户订单地址", description = "修改用户订单地址")
    public ServerResponseEntity<String> changeUserAddr(@RequestBody @Valid Order order) {
        Order orderDb = orderService.getOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderId, order.getOrderId())
                .eq(Order::getOrderNumber, order.getOrderNumber())
        );
        if (orderDb.getStatus() <= OrderStatus.PADYED.value() || Objects.equals(orderDb.getStatus(), OrderStatus.WAIT_GROUP.value())) {
            UserAddrOrder userAddrOrder = order.getUserAddrOrder();
            userAddrOrderService.updateAddrInfoById(userAddrOrder, orderDb);
        } else {
            // 订单状态异常，无法更改订单地址
            throw new YamiShopBindException("yami.order.status.error");
        }
        // 修改成功
        return ServerResponseEntity.success(ResponseEnum.OK.value(), I18nMessage.getMessage("yami.activity.update.success"));
    }

    @SysLog("修改订单备注")
    @PutMapping("/changeOrderRamark")
    @Operation(summary =  "修改订单备注", description = "修改订单备注")
    public ServerResponseEntity<String> changeOrderRamark(@RequestBody @Valid Order order) {
        Order orderDb = orderService.getOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderId, order.getOrderId())
                .eq(Order::getOrderNumber, order.getOrderNumber())
        );
        orderDb.setShopRemarks(order.getShopRemarks());
        orderService.updateById(orderDb);
        // 修改成功
        return ServerResponseEntity.success(ResponseEnum.SHOW_SUCCESS.value(), I18nMessage.getMessage("yami.activity.update.success"));
    }

    @GetMapping("/soldExcel")
    @Operation(summary =  "导出excel", description = "导出订单excel")
    public void soldExcel(@ParameterObject OrderParam orderParam, HttpServletResponse response) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        orderParam.setShopId(shopId);
        orderExcelService.soldExcel(orderParam, response);
    }

    @GetMapping("/unDeliveryOrderExcel")
    @Operation(summary =  "导出待发货订单", description = "导出待发货订单")
    @PreAuthorize("@pms.hasPermission('order:order:exportunorder')")
    public void unDeliveryOrderExcel(@ParameterObject OrderParam orderParam, HttpServletResponse response) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        orderParam.setShopId(shopId);
        orderExcelService.unDeliveryOrderExcel(orderParam, response);
    }

    @Operation(summary =  "导入待发货文件", description = "导入待发货文件")
    @PostMapping("/exportOrderExcel")
    @ResponseBody
    @PreAuthorize("@pms.hasPermission('order:order:exportunorder')")
    public ServerResponseEntity<String> exportOrderExcel(@RequestParam("orderExcelFile") MultipartFile orderExcelFile) throws Exception {
        if (Objects.isNull(orderExcelFile)) {
            throw new YamiShopBindException("yami.network.busy");
        }
        Long shopId = SecurityUtils.getShopUser().getShopId();
        List<UnDeliveryOrderExcelVO> orderList = new ArrayList<>();
        String errorMsg = orderExcelService.exportOrderExcel(orderExcelFile, shopId, orderList);
        if (Objects.nonNull(errorMsg)) {
            return ServerResponseEntity.success(errorMsg);
        }
        //无错误再发货
        for (UnDeliveryOrderExcelVO orderExcelVO : orderList) {
            DeliveryOrderItemParam deliveryOrderParam = new DeliveryOrderItemParam();
            deliveryOrderParam.setOrderNumber(orderExcelVO.getOrderNumber());
            deliveryOrderParam.setDeliveryType(orderExcelVO.getDvyType());
            if (Objects.equals(orderExcelVO.getDvyType(), DeliveryType.EXPRESS.getValue())) {
                deliveryOrderParam.setDvyFlowId(orderExcelVO.getDvyFlowId());
                deliveryOrderParam.setDvyId(orderExcelVO.getDvyId());
            }
            List<OrderItem> selectOrderItems = new ArrayList<>();
            for (OrderItem orderItem : orderExcelVO.getOrderItemList()) {
                OrderItem deliveryItem = new OrderItem();
                deliveryItem.setOrderItemId(orderItem.getOrderItemId());
                deliveryItem.setChangeNum(orderItem.getStatus() == -1 ? orderItem.getChangeNum() : orderItem.getStatus());
                deliveryItem.setStatus(orderItem.getStatus());
                deliveryItem.setProdCount(orderItem.getChangeNum());
                selectOrderItems.add(deliveryItem);
            }
            deliveryOrderParam.setSelectOrderItems(selectOrderItems);
            deliveryOrderService.saveDeliveriesInfo(deliveryOrderParam, shopId);
        }
        return ServerResponseEntity.success("导入成功！");
    }

    @GetMapping("/getOrderByUserId")
    @Operation(summary =  "分页获取用户订单列表", description = "分页获取用户订单列表")
    @Parameter(name = "userId", description = "用户id")
    public ServerResponseEntity<IPage<Order>> getOrderByUserId(PageParam<Order> page, String userId){
        Long shopId = SecurityUtils.getShopUser().getShopId();
        IPage<Order> pages = orderService.pageByUserIdAndShopId(page,userId,shopId);
        return ServerResponseEntity.success(pages);
    }

    @PostMapping("/orderCommissionSettlement")
    @Operation(summary = "测试用例方法调用订单结算接口" , description = "分页获取用户订单列表")
    public ServerResponseEntity<Void> orderCommissionSettlement(@RequestBody Order order){
        orderService.orderCommissionSettlement(Arrays.asList(order));
        return ServerResponseEntity.success();
    }

}
